<?php

namespace App\Models;

use App\Http\Common\Globals;
use App\Http\Common\MyUtils;
use App\Http\Controllers\BaseController;
use App\Models\Myquery\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Arr;

/**
 * 硬删除的基类 当列表 详情 修改删除等 都是 基础的简单的 没有多个关联的，用此基类会极大方便
 * Class BaseHard
 * @package App\Models
 */
class BaseModel extends Model
{
//    protected $with = [''];// 每次查询需要额外查询的外键对象
//    protected $appends = [''];// 每次都会自动查询出来的字段，比如 username 字段 需要配合 getUsernameAttribute 函数以自动获取其属性
    protected $hidden = [''];// 需要被隐藏的字段，不会被查询出来
    // use SoftDeletes; 是否使用软删除
    // 如果没有created_at 与 updated_at就是false,否则是true
    public $timestamps = true;
    // 不能写到数据库的字段
    protected $guarded = ['XDEBUG_SESSION_START','token','tokenType'];
    // 可以写入到数据库的字段
    protected $fillable = [];
    protected $perPage = 20;// 每页的数量
    public $query;// 查询的实例 query
    public $orderBy = "id desc";// 排序

    /**
     * 过滤条件 ，子函数直接覆写就行
     */
    public function condition(){
        if (!$this->query){
            $this->query = $this->newQuery();
        }
    }
    /**
     * 一般要先query,然后再运行 list 然后再是运行 count
     * 得到所有的 用户列表
     * @param $limit 每页多少
     * @return true
     */
    public function list($limit)
    {
        $this->condition();
        $this->orderBy();
        if ($limit==-1){
            return $this->query->get()->all(); // TODO: Change the autogenerated stub
        }
        return $this->query->simplePaginate($limit,['*'],BaseController::$frontPageName[0])->items(); // TODO: Change the autogenerated stub
    }
    /**
     * 计算总数
     * @return mixed
     */
    public function count()
    {
        $this->condition();
        return $this->query->count(); // TODO: Change the autogenerated stub
    }
    /**
     * 保存
     * @return int
     */
    public function  store(){
        return $this->save();
    }
    /**
     * 更新
     * @return int
     */
    public function  storeUpdate(){
        $m = self::find($this->getAttribute($this->primaryKey));
        if ($m){
            $all = $this->getAttributes();
            //额外的字段，修改不需要
            $ewai = $this->getMutatedAttributes();
            return $m->update(Arr::except($all,$ewai));
        }
        return $m;
    }
    /**
     * 删除
     * @return int
     */
    public function  storeDelete(){
        $temp = true;
        if ($t = $this->getAttribute($this->primaryKey)){
            $m = self::find($t);
            if ($m){
                $temp = $m->delete();
            }else{
                $temp = false;
            }
        }
        if ($t = $this->getAttribute($this->primaryKey.'s')){
            $temp = true;
            foreach ($t as $k=>$v){
                $m = self::find($v);
                if ($m) {
                    if ($m->delete()) {
                        continue;
                    }
                }
                Globals::$error .= " 第".($k+1)."条删除失败 ";
                $temp = false;
            }
        }
        return $temp;
    }
    public function sqlSearch($column, $condition, $value = '', $orAnd = ''){
        $c = $this->getAttribute($column);
        if ($value){
            $c = $value;
        }
        $whereAnd = 'where'.$orAnd;
        if ($c!=='' && $c!==null) {
            switch ($condition){
                case "like":
                    $this->query->$whereAnd($column,"like","%".$c."%");
                    break;
                case "=":
                    $this->query->$whereAnd($column,"=",$c);
                    break;
                case "between":
                    $this->query->whereBetween($column,$c);
                    break;
                case "null":
                    $this->query->whereNull($column);
                    break;
                case "raw":
                    $this->query->whereRaw($column);
                    break;
                default:
                    $this->query->$whereAnd($column,$condition,$c);
                    break;
            }
        }
    }
    public function storeDetail()
    {
        return self::find($this->getAttribute($this->primaryKey)); // TODO: Change the autogenerated stub
    }
    /**
     * 安全的拿到某个属性的值
     * @param mixed ...$args 第一个参数是对象，后面的分别为属性 可以有任意多个,当为当前模型的属性时就是用$this->getOriginal("asd")
     * @return mixed|string
     * 接收方式 post
     * 接收参数 @param1
     */
    public function getAttributeSafety(...$args){
        $res = $args[0];
        if (!$res){
            return "";
        }
        foreach ($args as $k=>$v){
            if ($k>0){
                $res = $res->$v;
                if (!$res){
                    return "";
                }
            }
        }
        return $res;
    }
    /**
     * 得到唯一的code 订单的编号 32 位
     * @param $class
     * @param string $name
     * @return string
     */
    public function getUniqueCode($class,$name='code'){
        // 得到唯一的openId
        $code = date('Ymdhms').MyUtils::randMath(6);
        $codeCount = $class::where($name,$code)->get()->count();
        // 不为空 再生成一遍
        if ($codeCount) $code = $this->getUniqueCode($class);
        return $code;
    }

    /**
     * 排序
     * @return mixed
     */
    public function orderBy()
    {
        $t = explode(' ',$this->orderBy);
        if ($t && count($t)){
            if (in_array('desc',$t)){
                return $this->query->orderByDesc($t[0]); // TODO: Change the autogenerated stub
            }else{
                return $this->query->orderBy($t[0]); // TODO: Change the autogenerated stub
            }
        }
    }
    /**
     * 为模型创建一个新的有说服力的查询生成器。
     * @param $query
     * @return Builder
     */
    public function newEloquentBuilder($query)
    {
        // 返回的是我自己的builder
        return new Builder($query);
    }
}
